From 1a827a098413dcaa47d5c18c1c8ece194ef06bfa Mon Sep 17 00:00:00 2001 From: Krinkle Date: Thu, 23 Dec 2010 23:34:32 +0000 Subject: [PATCH] Improving jquery.makeCollapsible: * Setting toggle function in a variable to easier reuse it through the plugin * Replace "-hide" and "-show" classes with "expanded" and "collapsed" respectively * For more flexibility, if there's a toggle-element already, bind the function to it and use it instead. Otherwise, just create one as usual. See [[betawiki:User:Krinkle/CollapsingTestpageKr#footer|CollapsingTestpageKr#Combination example]] ** It's more likely that the source has a custom position of the togglelink waiting for it to be bound, then it to be already bound. * Some comments improved * Message key "hide" to "collapsible-collapse" (Follow-up r78915 CR) * Message key "show" to "collapsible-expand" * Changed toggle-link content filling from html() to text() (message errors like caused an HTML-element to be created) --- resources/Resources.php | 1 + resources/jquery/jquery.makeCollapsible.css | 8 +- resources/jquery/jquery.makeCollapsible.js | 150 +++++++++++++------- 3 files changed, 101 insertions(+), 58 deletions(-) diff --git a/resources/Resources.php b/resources/Resources.php index d4f0a08236..d9152b6e84 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -81,6 +81,7 @@ return array( 'jquery.makeCollapsible' => array( 'scripts' => 'resources/jquery/jquery.makeCollapsible.js', 'styles' => 'resources/jquery/jquery.makeCollapsible.css', + 'messages' => array( 'collapsible-expand', 'collapsible-collapse' ), ), 'jquery.suggestions' => array( 'scripts' => 'resources/jquery/jquery.suggestions.js', diff --git a/resources/jquery/jquery.makeCollapsible.css b/resources/jquery/jquery.makeCollapsible.css index 78d847d288..19d47784b5 100644 --- a/resources/jquery/jquery.makeCollapsible.css +++ b/resources/jquery/jquery.makeCollapsible.css @@ -2,12 +2,12 @@ .kr-collapsible-toggle { float:right; } -.kr-collapsible-toggle-hide, -.kr-collapsible-toggle-hide a { +.kr-collapsible-toggle-expanded, +.kr-collapsible-toggle-expanded a { cursor:n-resize; } -.kr-collapsible-toggle-show, -.kr-collapsible-toggle-show a { +.kr-collapsible-toggle-collapsed, +.kr-collapsible-toggle-collapsed a { cursor:s-resize; } /* list-items go as wide as their parent element, don't float them inside list items */ diff --git a/resources/jquery/jquery.makeCollapsible.js b/resources/jquery/jquery.makeCollapsible.js index eb40482678..c5e1c5a1bc 100644 --- a/resources/jquery/jquery.makeCollapsible.js +++ b/resources/jquery/jquery.makeCollapsible.js @@ -20,62 +20,78 @@ $.fn.makeCollapsible = function() { return this.each(function() { + var $that = $(this).addClass( 'kr-collapsible' ), // in case $( '#myAJAXelement' ).makeCollapsible() was called that = this, collapsetext = $(this).attr( 'data-collapsetext' ), - expandtext = $(this).attr( 'data-expandtext' ); + expandtext = $(this).attr( 'data-expandtext' ), + toggleFunction = function( that ) { + var $that = $(that), + $collapsible = $that.closest( '.kr-collapsible.kr-made-collapsible' ).toggleClass( 'kr-collapsed' ); + + // It's expanded right now + if ( $that.hasClass( 'kr-collapsible-toggle-expanded' ) ) { + // Change link to "Show" + $that.removeClass( 'kr-collapsible-toggle-expanded' ).addClass( 'kr-collapsible-toggle-collapsed' ); + if ( $that.find( '> a' ).size() ) { + $that.find( '> a' ).text( expandtext ); + } else { + $that.text( expandtext ); + } + // Hide the collapsible element + if ( $collapsible.is( 'table' ) ) { + // Hide all direct childing table rows of this table, except the row containing the link + // Slide doens't work, but fade works fine as of jQuery 1.1.3 + // http://stackoverflow.com/questions/467336/jquery-how-to-use-slidedown-or-collapsed-function-on-a-table-row#920480 + // Stop to prevent animations from stacking up + $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop( true, true ).fadeOut(); + + } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) { + $collapsible.find( '> li' ).not( $that.parent() ).stop( true, true ).slideUp(); + + } else { //
,

etc. + $collapsible.find( '> .kr-collapsible-content' ).slideUp(); + } + + // It's collapsed right now + } else { + // Change link to "Hide" + $that.removeClass( 'kr-collapsible-toggle-collapsed' ).addClass( 'kr-collapsible-toggle-expanded' ); + if ( $that.find( '> a' ).size() ) { + $that.find( '> a' ).text( collapsetext ); + } else { + $that.text( collapsetext ); + } + // Show the collapsible element + if ( $collapsible.is( 'table' ) ) { + $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop( true, true ).fadeIn(); + + } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) { + $collapsible.find( '> li' ).not( $that.parent() ).stop( true, true ).slideDown(); + + } else { //

,

etc. + $collapsible.find( '> .kr-collapsible-content' ).slideDown(); + } + } + return; + }; + // Use custom text or default ? if( !collapsetext || collapsetext == '' ){ - collapsetext = mw.msg( 'hide' ); + collapsetext = mw.msg( 'collapsible-collapse' ); } if ( !expandtext || expandtext == '' ){ - expandtext = mw.msg( 'show' ); + expandtext = mw.msg( 'collapsible-expand' ); } - // Create toggle link with a space around the brackets ( ) - $toggleLink = $( ' [' + collapsetext + '' ).click( function(){ - var $that = $(this), - $collapsible = $that.closest( '.kr-collapsible.kr-made-collapsible' ).toggleClass( 'kr-collapsed' ); - if ( $that.hasClass( 'kr-collapsible-toggle-hide' ) ) { - // Change link to "Show" - $that - .removeClass( 'kr-collapsible-toggle-hide' ).addClass( 'kr-collapsible-toggle-show' ) - .find( '> a' ).html( expandtext ); - // Hide the collapsible element - if ( $collapsible.is( 'table' ) ) { - // Hide all direct childing table rows of this table, except the row containing the link - // Slide doens't work, but fade works fine as of jQuery 1.1.3 - // http://stackoverflow.com/questions/467336/jquery-how-to-use-slidedown-or-show-function-on-a-table-row#920480 - // Stop to prevent animaties from stacking up - $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop(true, true).fadeOut(); - - } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) { - $collapsible.find( '> li' ).not($that.parent()).stop(true, true).slideUp(); - } else { //

,

etc. - $collapsible.find( '> .kr-collapsible-content' ).slideUp(); - } - - } else { - // Change link to "Hide" - $that - .removeClass( 'kr-collapsible-toggle-show' ).addClass( 'kr-collapsible-toggle-hide' ) - .find( '> a' ).html( collapsetext ); - // Show the collapsible element - if ( $collapsible.is( 'table' ) ) { - $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop(true, true).fadeIn(); - - } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) { - $collapsible.find( '> li' ).not( $that.parent() ).stop(true, true).slideDown(); - - } else { //

,

etc. - $collapsible.find( '> .kr-collapsible-content' ).slideDown(); - } - } - return false; + // Create toggle link with a space around the brackets ( [text] ) + var $toggleLink = $( '' ).text( collapsetext ).wrap( '' ).parent().prepend( ' [' ).append( '] ' ).click( function(e){ + e.preventDefault(); + toggleFunction( this ); } ); // Skip if it has been enabled already. - if ($that.hasClass( 'kr-made-collapsible' )) { + if ( $that.hasClass( 'kr-made-collapsible' ) ) { return; } else { $that.addClass( 'kr-made-collapsible' ); @@ -84,19 +100,36 @@ $.fn.makeCollapsible = function() { // Elements are treated differently if ( $that.is( 'table' ) ) { // The toggle-link will be in the last cell (td or th) of the first row - var $lastCell = $( 'tr:first th, tr:first td', that ).eq(-1); - if ( !$lastCell.find( '> .kr-collapsible-toggle' ).size() ) { + var $lastCell = $( 'tr:first th, tr:first td', that ).eq(-1), + $toggle = $lastCell.find( '> .kr-collapsible-toggle' ); + + if ( !$toggle.size() ) { $lastCell.prepend( $toggleLink ); + } else { + $toggleLink = $toggle.unbind( 'click' ).click( function( e ){ + e.preventDefault(); + toggleFunction( this ); + } ); } - } else if ($that.is( 'ul' ) || $that.is( 'ol' )) { - if ( !$( 'li:first', $that).find( '> .kr-collapsible-toggle' ).size() ) { - // Make sure the numeral count doesn't get messed up, reset to 1 unless value-attribute is already used - if ( $( 'li:first', $that ).attr( 'value' ) == '' ) { - $( 'li:first', $that ).attr( 'value', '1' ); + } else if ( $that.is( 'ul' ) || $that.is( 'ol' ) ) { + // The toggle-link will be in the first list-item + var $firstItem = $( 'li:first', $that), + $toggle = $firstItem.find( '> .kr-collapsible-toggle' ); + + if ( !$toggle.size() ) { + // Make sure the numeral order doesn't get messed up, reset to 1 unless value-attribute is already used + if ( $firstItem.attr( 'value' ) == '' ) { + $firstItem.attr( 'value', '1' ); } $that.prepend( $toggleLink.wrap( '

  • ' ).parent() ); - } + } else { + $toggleLink = $toggle.unbind( 'click' ).click( function( e ){ + e.preventDefault(); + toggleFunction( this ); + } ); + } + } else { //
    ,

    etc. // Is there an content-wrapper already made ? // If a direct child with the class does not exists, create the wrap. @@ -104,11 +137,20 @@ $.fn.makeCollapsible = function() { $that.wrapInner( '

    ' ); } - // Add toggle-link if not present - if ( !$that.find( '> .kr-collapsible-toggle' ).size() ) { + // The toggle-link will be the first child of the element + var $toggle = $that.find( '> .kr-collapsible-toggle' ); + + if ( !$toggle.size() ) { $that.prepend( $toggleLink ); + } else { + $toggleLink = $toggle.unbind( 'click' ).click( function( e ){ + e.preventDefault(); + toggleFunction( this ); + } ); } + } + console.log( $toggleLink.get(0) ); // Initial state if ( $that.hasClass( 'kr-collapsed' ) ) { $toggleLink.click(); -- 2.20.1